package com.gimi.cloud.mmf.gateway.config.jpa;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;


/**
 * JPA配置
 * @author zhoufuhang
 * @time 2017年12月5日
 */
public class BaseRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>  implements BaseRepository<T, ID> {

	//实体管理类，对持久化实体做增删改查，自动义sq操作模板所需要的核心类  
    public final EntityManager entityManager;  

	public BaseRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
		super(domainClass, entityManager);
		this.entityManager = entityManager;
	}

	@Override
	public List<?> findAllByParams(String sql, Object... args) {
		Query q =  entityManager.createNativeQuery(sql);
         //查询结果转map          
        q.unwrap(SQLQuery.class).setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);  
        int i = 0;  
        for (Object arg : args) {  
            q.setParameter(++i, arg);  
        }  
        return q.getResultList();  
	}

	@Override
	public Page<?> findPageByParams(String sql, Pageable pageable, Object... args) {
		Query countq = entityManager.createNativeQuery("select count(*) FROM (" + sql + ") as a");
		
		Query q = entityManager.createNativeQuery(sql);
        q.unwrap(SQLQuery.class).setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);  
        
        int i = 0;  
        for (Object arg : args) { 
        	++i;
        	countq.setParameter(i, arg);  
        	q.setParameter(i, arg); 
        }  
		int totalCount =  ((Number) countq.getSingleResult()).intValue();
		
        q.setFirstResult(pageable.getPageSize() * (pageable.getPageNumber() - 1));  
        q.setMaxResults(pageable.getPageSize());  
		List<?> pageCount = q.getResultList();  
        Page<?> pages = new PageImpl<>(pageCount, pageable, totalCount);  
        return pages;  
	}

}
